package com.example.demo.ShiroConfig;


import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @Author
 * @Description
 *  * 当配置了多个Realm时，我们通常使用的认证器是shiro自带的org.apache.shiro.authc.pam.ModularRealmAuthenticator，其中决定使用的Realm的是doAuthenticate()方法
 *  * 自定义Authenticator
 *  * 注意，当需要分别定义处理学生和教师和管理员验证的Realm时，对应Realm的全类名应该包含字符串“Student”“Teacher”，或者“Admin”。
 *  *  * 并且，他们不能相互包含，例如，处理学生验证的Realm的全类名中不应该包含字符串"Admin"。
 *
 * @Date 2019/10/2 9:07
 * @vsersion 1.0.0
 **/
public class UserModularRealmAuthenticator extends ModularRealmAuthenticator {


    @Autowired
    NOPASSWD myRealm;
    @Autowired
    PASSWORD PASSWORD;

    @Override
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 判断getRealms()是否返回为空
        assertRealmsConfigured();
        // 强制转换回自定义的CustomizedToken
        CustomeToken userToken = (CustomeToken) authenticationToken;
        // 登录类型
        String loginType = (userToken.getType()).toString();
        // 所有Realm
        Collection<Realm> realms = getRealms();
        // 登录类型对应的所有Realm
        Collection<Realm> typeRealms = new ArrayList<>();

        for (Realm realm : realms) {
            System.out.println(loginType.toString()+"登录方式");
            //根据realm的类名和loginType对比来决定哪个realm起作用
            if (realm.getName().contains(loginType))  // 注：这里使用类名包含枚举，区分realm
            typeRealms.add(realm);
        }

        // 判断是单Realm还是多Realm
        if (typeRealms.size() == 1){
            System.out.println("发现一个realm");
            return doSingleRealmAuthentication(((ArrayList<Realm>) typeRealms).get(0), userToken);
        }
        else{
            System.out.println("发现多个realm");
            return doMultiRealmAuthentication(typeRealms, userToken);
        }
    }
}

